home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
news
/
readers
/
skim-0.8
/
skim-0
/
skim-0.8.4
/
SkimUtils.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-02-18
|
9KB
|
446 lines
/*
* NAME
* SkimUtils.c
* DESCRIPTION
* Miscellaneous skim related utility functions.
* COPYRIGHT
* Skim - Off-line news reading package optimized for slow lines.
* Copyright (C) 1996 Rene W.J. Pijlman
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* VERSION
* Skim version 0.8.4.
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <sys/wait.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
#include "Skim.h"
#include "SkimUtils.h"
#include "StandardIO.h"
FILE_ID("$Header: /home/rene/sys/CVS_MasterSourceRepository/skim/SkimUtils.c,v 1.7 1996/02/17 19:38:52 rene Exp $");
char * SkimDirectory( void )
{
char * SkimDirectory;
if ( ( SkimDirectory = getenv( "SKIMDIR" ) ) == NULL )
{
SIOPrintf( StandardError,
"Environment variable SKIMDIR is not set.\n" );
exit( EXIT_FAILURE );
}
return SkimDirectory;
}
Boolean AppendFieldFromSeparatorRecord(
VarBuf Target,
VarBuf Overview,
char Separator,
unsigned int InputOffset,
void (Convert)(VarBuf) )
{
VarBuf Scratch = VBCreate();
Boolean Success = True;
char * p = VBAsString( Overview );
int i;
for ( i = 0; Success && i < InputOffset; i++ )
{
p = strchr( p, Separator );
if ( p != NULL )
{
p++;
}
else
{
Success = False;
}
}
if ( Success )
{
for ( ; *p != '\0' && *p != Separator; p++ )
{
VBAppendCharacter( Scratch, *p );
}
if ( Convert != NULL )
{
Convert( Scratch );
}
VBAppendVB( Target, Scratch );
}
VBDestroy( Scratch );
return Success;
}
Boolean AppendFieldFromFixedRecord(
VarBuf Target,
VarBuf Record,
unsigned int Offset,
int Length,
void (Convert)(VarBuf) )
{
VarBuf Scratch = VBCreate();
Boolean Success = True;
char * From;
assert( Length == VARIABLE_LENGTH || Length >= 0 );
if ( ( Length == VARIABLE_LENGTH && VBSize( Record ) < Offset ) ||
( VBSize( Record) < Offset + Length ) )
{
Success = False;
}
else
{
From = VBAsString(Record) + Offset;
if ( Length == VARIABLE_LENGTH )
{
VBAppendString( Scratch, From );
}
else
{
unsigned int i;
for ( i = 0; i < Length; i ++ )
{
VBAppendCharacter( Scratch, *(From + i) );
}
}
if ( Convert != NULL )
{
Convert( Scratch );
}
VBAppendVB( Target, Scratch );
}
VBDestroy( Scratch );
return Success;
}
void WaitForAChild( const char * ProgramName )
{
int Status;
if ( wait( &Status ) <= 0 )
{
SIOPrintError( "wait" );
exit( EXIT_FAILURE );
}
if ( !WIFEXITED( Status ) )
{
SIOPrintf( StandardError,
"Warning: '%s' process terminated with an error.\n",
ProgramName );
}
}
int OffsetOfSelection( void )
{
return 0;
}
int OffsetOfArticleNumber( void )
{
return OffsetOfSelection() + LengthSelection + 1;
}
int OffsetOfAuthor( void )
{
return OffsetOfArticleNumber() + LengthArticleNumber + 1;
}
int LengthOfAuthor( void )
{
static int Length = 0;
if ( Length == 0 )
{
char * p = getenv( "SKIMLENGTHAUTHOR" );
if ( p != NULL )
{
Length = atoi( p );
if ( Length < 1 )
{
SIOPrintf( StandardError,
"invalid value in environment variable SKIMLENGTHAUTHOR: %s", p );
exit( EXIT_FAILURE );
}
}
else
{
Length = DefaultLengthOfAuthor;
}
}
return Length;
}
int LengthOfNumberOfLines( void )
{
static int Length = 0;
if ( Length == 0 )
{
char * p = getenv( "SKIMLENGTHLINES" );
if ( p != NULL )
{
Length = atoi( p );
if ( Length < 1 )
{
SIOPrintf( StandardError,
"invalid value in environment variable SKIMLENGTHNUMBEROFLINES: %s", p );
exit( EXIT_FAILURE );
}
}
else
{
Length = DefaultLengthOfNumberOfLines;
}
}
return Length;
}
int OffsetOfLines( void )
{
return OffsetOfAuthor() + LengthOfAuthor() + 1;
}
int OffsetOfSubject( void )
{
return OffsetOfLines() + LengthOfNumberOfLines() + 1;
}
/*
* `Target' contains the `From:' header field of a USENET article. Parse the
* field, and extract the real name of the author.
*
* The formats which are recognized are the formats allowed by RFC-1036:
*
* 1) email@subdomain.domain (Real Name)
* 2) Real Name <email@subdomain.domain>
* 3) email@subdomain.domain
*
* In pattern 2, double quote characters (") are removed, since some posters
* appear to use formats like:
*
* 4) "Real Name" <email@subdomain.domain>
*
* When there is no real name (as in pattern 3) or when the `From:' header
* field is not is one of the allowed formats, no conversion is applied
* (except for pattern 5 below).
*
* A trailing string "()" is removed from the resulting Author field, since
* some posters use formats like:
*
* 5) email@subdomain.domain ()
*/
void AuthorFromFromField( VarBuf Target )
{
VarBuf From = VBCreate();
char * LeftBracket;
char * RightBracket;
char * FromAsString;
char * p;
VBAppendVB( From, Target );
VBReset( Target );
FromAsString = VBAsString(From);
/* Pattern 1. */
if ( ( LeftBracket = strchr( FromAsString, '(' ) ) != NULL &&
( RightBracket = strchr( FromAsString, ')' ) ) != NULL &&
LeftBracket > FromAsString &&
RightBracket > LeftBracket )
{
for ( p = LeftBracket + 1; p < RightBracket; p++ )
{
VBAppendCharacter( Target, *p );
}
}
/* Pattern 2. */
else if ( ( LeftBracket = strchr( FromAsString, '<' ) ) != NULL &&
( RightBracket = strchr( FromAsString, '>' ) ) != NULL &&
LeftBracket > FromAsString &&
RightBracket > LeftBracket )
{
for ( p = FromAsString; p < LeftBracket; p++ )
{
if ( *p != '"' )
{
VBAppendCharacter( Target, *p );
}
}
}
VBRemoveLeadingBlanks( Target );
VBRemoveTrailingBlanks( Target );
/*
* This also catches the case where () is empty or blank in pattern 1, or
* only blanks preceed <> in pattern 2.
*/
if ( VBSize( Target ) == 0 )
{
VBAppendVB( Target, From );
VBRemoveLeadingBlanks( Target );
VBRemoveTrailingBlanks( Target );
}
if ( VBSize(Target) > 2 &&
VBAsString(Target)[ VBSize(Target) - 2 ] == '(' &&
VBAsString(Target)[ VBSize(Target) - 1 ] == ')' )
{
VBTruncate( Target, VBSize(Target) - 2 );
VBRemoveLeadingBlanks( Target );
VBRemoveTrailingBlanks( Target );
}
VBDestroy( From );
}
char * HomeDirectory( void )
{
char * HomeDir;
HomeDir= getenv("HOME");
if ( HomeDir== NULL )
{
struct passwd * passwd_entry = getpwuid( getuid() );
if ( passwd_entry != NULL )
{
assert( passwd_entry->pw_dir != NULL );
HomeDir= passwd_entry->pw_dir;
}
else
{
SIOPrintError("getpwuid");
exit( EXIT_FAILURE );
}
}
return HomeDir;
}
VarBuf GetSignature( void )
{
VarBuf New = NULL;
VarBuf SignatureFileName = VBCreate();
StandardIO SignatureFile = SIOCreate();
VBPrintf( SignatureFileName, "%s/.signature", HomeDirectory() );
SIOFileOpen( SignatureFile, VBAsString(SignatureFileName),
OpenModeReadIgnore );
if ( SIOIsOpenForRead(SignatureFile) )
{
New = VBCreate();
VBReadFile( New, SignatureFile );
}
VBDestroy(SignatureFileName);
SIODestroy(SignatureFile);
return New;
}
void ItemsFromEnvironment(
VarBuf * Signature,
VarBuf * X_NewsReader,
VarBuf * From,
VarBuf * ReplyTo,
VarBuf * Path,
VarBuf * Organization )
{
char * p;
assert( Signature != NULL && *Signature == NULL );
assert( X_NewsReader != NULL && *X_NewsReader == NULL );
assert( From != NULL && *From == NULL );
assert( ReplyTo != NULL && *ReplyTo == NULL );
assert( Path != NULL && *Path == NULL );
assert( Organization != NULL && *Organization == NULL );
*Signature = GetSignature();
p = getenv("SKIMFROM");
if ( p != NULL )
{
*From = VBCreate();
VBAppendString( *From, p );
}
p = getenv("SKIMPATH");
if ( p != NULL )
{
*Path = VBCreate();
VBAppendString( *Path, p );
}
p = getenv("SKIMREPLYTO");
if ( p != NULL )
{
*ReplyTo = VBCreate();
VBAppendString( *ReplyTo, p );
}
p = getenv("SKIMORGANIZATION");
if ( p != NULL )
{
*Organization = VBCreate();
VBAppendString( *Organization, p );
}
*X_NewsReader = VBCreateString("skim 0.8.4" );
}